// TeXworksScript
// Title:  Seventy Four
// Description: tests Tonys ideas of English letters adding up to seventy four for gospel words compared to the number of natrual English words that do internally add up to 74
// Author:  Paul A Norman
// Version: 0.1
// Date: 2020-03-21
// Script-Type: standalone
// Context: TeXDocument
// Shortcut: Alt+S, Alt+7, Alt+4


//  Comment if NOT Needed - This includes PhpJs ($P), twConst, msgBox, twPan ($tw), string.toTitleCase() 
 // eval(TW.app.getGlobal("helper_twPan")); 

// Encapsulate usage here of the TeXworks Scripting global variable "TW"
// If wishing to run this script in another host environment - adjust these external Object calls accordingly...

  var twPan = {
   alert : function(text){
    TW.information( null, "Message", text);
   }
  };
   var document = {

    write : function(text){
  
      TW.target.insertText(text);
    },

    getData : function (filePath, storeInArray){ // this is synchrenous
      var retVal = TW.readFile(filePath);
  
      if  (retVal.status == 0) // SystemAccess_OK
      
           {
             var openedDocument = retVal["result"] ;
             storeInArray = openedDocument.split("\n"); 
  
             return storeInArray;
      
          }else{
                  twPan.alert(filePath + '\n\n Could not be Opened\n\nPlease Check it is Available.');
                  }
  
    }
   };
   
   var dictionaryWordsFile, workingWith;
   
    switch (TW.getItem(null, "KJV, or English Dictionary - SCOWL-90"

                     , "Please Make a Choice"

                      , ["KJV", "SCOWL-90"]

                        , 1 //  1 - SCOWL-90 will be default - zero based index, true - here means can edit
                     
                          , true
                               )){  
  case "KJV":
    workingWith = "KJV Unique";
    dictionaryWordsFile = "./seventyFour/pdf/bible-kjv/lazarus_produced_KJV_unique_words.txt";
  break;
  
  case  "SCOWL-90":
  case undefined:
  workingWith = "Ispell Large English Dictionary";
        dictionaryWordsFile = "./seventyFour/pdf/SCOWL-90/SCOWL 90 words.txt"; // Biggest reliable list available it seems;
    }
    
    twPan.alert(workingWith);
    
  //  exit; // halt by error here
 
 var dictionaryWords = [];
  var equal74 = [];

 var notableWordsFile = "./seventyFour/pdf/key words.tex" 
 var notableWords = [];
  var indexNotableWords = [];
  var descriptionsNotableWords= [];

  var section = "section"; 
  var subsection ="sub" + section;
  var subsubsection = "sub" + subsection; 
 
 
 
  var checkNumber = 74;
  var checkNumber = TW.getText(null, "Please Confirm test Number: ", checkNumber, checkNumber);
  // twPan.alert(checkNumber);
  
 
  
    var   wordFirstLetter = "",  wordSecondLetter = "";

    const asciiOffset =  64; // A is ascii 65, in Tony's scheme it is 1, B is 2, C is 3, et al...
  
    var letterList = [];
 // build array of letter values
   for (i=1;  i<27; i++ ){  
    letterList[String.fromCharCode(i +asciiOffset )] = i ; // "A" = 1, "B" = 2 ... "Z" = 26    
   } 
  
  //  twPan.alert(letterList['Z']); // 90 ok  
  

  

  function prepareIndexAndDescriptions(){

    // scope issues on passing an array by reference and value so...
    notableWords = document.getData(notableWordsFile, notableWords);

    for (nW = 0; nW < notableWords.length; nW++){

         if (notableWords[nW].indexOf(" - ") == -1){
             
          indexNotableWords.push(notableWords[nW].trim())

         }else{
          var buildDescription = notableWords[nW].split(" - ");

          indexNotableWords.push(buildDescription[0].trim());
          descriptionsNotableWords[buildDescription[0].trim()] = buildDescription[1].trim();
         } 
    }
 /*
    twPan.alert(   "Index: " + indexNotableWords.length

              + "\nWith Description: "  +  Object.keys(descriptionsNotableWords).length
              
              + "\n\nHas X-kadishim: \n" + hasDescription("kadishim") );  
   */           
 }
 
  function hasDescription(testWord){

    /* if array descriptionsNotableWords does not have our testWord 
       it will return an unusual JavaScript parameter: undefined 
       which can be triclky to test for accurately/consistently, 
       (Qt ECMA is unkonow here and may change over versions);

     So force a cast to a string with + "" then test.
    */

    var test = descriptionsNotableWords[testWord] + ""; 

    return (test !== 'undefined');
  }

  function isNotableWord(testWord){
  
    return indexNotableWords.indexOf(testWord) !== -1; 

  }
            
  function pos(needle, inHaystack){
  
              return inHaystack.indexOf(needle, 0);
  
  }
  
 

  
 function toc(level, heading){
 // level one of section, subsection, subsubsection for Table of Contents
 
    document.write("\n\\phantomsection");
    
    document.write("\n\\addcontentsline{toc}{" +level
      +"}{"+heading+"}");
    
    document.write("\n\\"+ level+"*{" 
        + heading + "}\n");
  
 }

  function processAndWrite(){
    function showNumbers(currentWord){

      var letterNumbersSequence = "";
    
      for (i =0; i < currentWord.length; i++){       
           
               letterNumbersSequence += letterList[currentWord[i].toUpperCase()] + " ";  
               // force a cast to string - ensure not treated as a number
           }   
    
       return letterNumbersSequence;
    }

    var stillProperNouns = true;
  var goingToSmallLetters = false;
  
  //  twPan.alert(equal74.length + " / " + dictionaryWords.length);
  
 document.write( "\\noindent Total Words Internally Adding Upto "+checkNumber+": "+ equal74.length + "\\\\\nOut of: " + dictionaryWords.length 
                                + " "  + workingWith  + " Words\n\n");
                                    
  document.write("\n");
    toc(section, "{Proper Nouns \\bf\\Large}");
  document.write("\n");                                    
  
 document.write("\\begin{multicols}{5}")  
    
  
  for (word74 in equal74){
  
    currentWord = equal74[word74].trim();

    
  
    if ( (currentWord[0] == 'a') & (stillProperNouns)  ){
    
        stillProperNouns = false;
         
         document.write("\n");
         
         document.write("\\end{multicols}\n\n");
         
          goingToSmallLetters = true;
         
       
        document.write("\n\n\n");
 toc(section, "{Lower-Case Words \\bf\\Large}");
      document.write("\n");
          
           document.write("\\setcounter{section}{0}");
          
           document.write("\\begin{multicols}{5}\n\n");           
           
    }
    
    if (  wordFirstLetter != currentWord[0] ){
          wordFirstLetter  = currentWord[0];
          
 /*        if ( goingToSmallLetters){
              goingToSmallLetters = false; // skip when leaving Big letters
           }else{
             document.write("\\vfill\n");
           }
 */          
          
    //      document.write("\\columnbreak\n");
          toc(section, "{\\bf " + wordFirstLetter + "}");
           
    }
    
     
    if (currentWord.length != 1){
      
    if (   wordSecondLetter != currentWord[1] ){
           wordSecondLetter  = currentWord[1];
          
          document.write("\n\\phantomsection\n");
          toc(subsection,  "\\textcolor{OliveDrab}{"+ wordFirstLetter 
              + "}" +wordSecondLetter);
           
    }}

      var footnote = "";      
        
   if (isNotableWord(currentWord)){
              
         if (hasDescription(currentWord)){
          footnote = "\\footnote{" + currentWord + " - " + descriptionsNotableWords[currentWord] + "} ";

         }


          document.write("\\index{" + currentWord + footnote + '}');
          
        }

        document.write(footnote + "\\begin{minipage}{\\columnwidth}\n" 
                         + currentWord  + '\\\\\n');
        document.write("{\\scriptsize " 
                          + showNumbers(currentWord) 
                          + "}\\\\*[2pt]\n\\end{minipage}\n");
  }
  
   document.write("\\end{multicols}");
    
   document.write("\n\n% End of: " + workingWith); 
} 
  

function initialise(){

  // scope issues on passing an array by reference and value so...
  dictionaryWords = document.getData(dictionaryWordsFile, dictionaryWords);
  

  prepareIndexAndDescriptions();

 var firstLatter, secondLetter, currentWord;
 var lettersAddUpTo = 0;
 
for (J =0; J <  dictionaryWords.length; J++){

 currentWord = dictionaryWords[J].toUpperCase();
 
 if (pos(String.fromCharCode(39), currentWord) != -1){continue;} // not interested in words with apostrophes 

// if (equal74.indexOf(currentWord) != -1){continue;} // already in list - dairetic marking and grave and acute etc were simplified in the construction of the word list to give pure English letters - so some apparent double ups to be detected

// Testing only --
//  if ( J >250){  twPan.alert(currentWord);}
      
       for (i =0; i < currentWord.length; i++){       
     
    // Testing only --    
    //    if ( J >250){ twPan.alert(currentWord[i]);}
       
           lettersAddUpTo += letterList[currentWord[i]] *1;  // force a cast to number - ensure not treated as a string
           
       
       }       
          if  (lettersAddUpTo == checkNumber){
           equal74.push(dictionaryWords[J]);  // currentWord.toLowerCase()
         
                }    
     lettersAddUpTo = 0;
     
 // Testing only --      
//  if ( J == 260){  break; }
  } 
}



    initialise();   
 
    processAndWrite();

    twPan.alert("Total: "+ equal74.length + "\\\\\nOut of: " + dictionaryWords.length );

    
  
  /*
  Dictionary acknowledgement...
  
  This file contains the contents of the Ispell (ver 3.1.20) word list after
being expand from there affix compressed form used by Ispell.

Ispell can be found at http://fmg-www.cs.ucla.edu/geoff/ispell.html.
This wordlist can be found at http://wordlist.sourceforge.net/

These word lists are under the same copyright as Ispell itself:

  Copyright 1993, Geoff Kuenning, Granada Hills, CA
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
  3. All modifications to the source code must be clearly marked as
     such.  Binary redistributions based on modified source code
     must be clearly marked as modified versions in the documentation
     and/or other materials provided with the distribution.
  4. All advertising materials mentioning features or use of this software
     must display the following acknowledgment:
     This product includes software developed by Geoff Kuenning and
     other unpaid contributors.
  5. The name of Geoff Kuenning may not be used to endorse or promote
     products derived from this software without specific prior
     written permission.

  THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS
  IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GEOFF
  KUENNING OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
  */